<template>
  <!-- 搜索工作栏 -->
  <ContentWrap>
    <el-form
      class="-mb-15px"
      :model="queryParams"
      ref="queryFormRef"
      :inline="true"
      label-width="80px"
    >
      <el-form-item label="时间范围" prop="times">
        <el-date-picker
          v-model="queryParams.times"
          value-format="YYYY-MM-DD"
          type="daterange"
          start-placeholder="开始日期"
          end-placeholder="结束日期"
          :default-time="[new Date('1 00:00:00'), new Date('1 23:59:59')]"
          :shortcuts="shortcuts"
          class="!w-240px"
        />
        <!-- <el-date-picker
          v-model="queryParams.times"
          value-format="YYYY-MM-DD"
          type="daterange"
          start-placeholder="开始日期"
          end-placeholder="结束日期"
          :default-time="[new Date('1 00:00:00'), new Date('1 23:59:59')]"
          class="!w-320px"
        /> -->
      </el-form-item>

      <el-form-item label="日志级别" prop="level">
        <el-select
          v-model="queryParams.level.operator"
          placeholder="请选择条件"
          clearable
          style="width: 100px; margin-right: 10px"
        >
          <el-option
            v-for="dict in getStrDictOptions(DICT_TYPE.SYSTEM_OPERATOR_TYPE)"
            :key="dict.value"
            :label="dict.label"
            :value="dict.value"
          />
        </el-select>
        <el-select
          v-model="queryParams.level.value"
          placeholder="请选择日志级别"
          clearable
          class="!w-160px"
        >
          <el-option label="DEBUG" value="DEBUG" />
          <el-option label="INFO" value="INFO" />
          <el-option label="WARN" value="WARN" />
          <el-option label="ERROR" value="ERROR" />
        </el-select>
      </el-form-item>

      <el-form-item label="应用名称" prop="appName">
        <el-select
          v-model="queryParams.appName.operator"
          placeholder="请选择条件"
          clearable
          style="width: 100px; margin-right: 10px"
        >
          <el-option
            v-for="dict in getStrDictOptions(DICT_TYPE.SYSTEM_OPERATOR_TYPE)"
            :key="dict.value"
            :label="dict.label"
            :value="dict.value"
          />
        </el-select>
        <el-input
          v-model="queryParams.appName.value"
          placeholder="请输入应用名称"
          clearable
          class="!w-200px"
        />
      </el-form-item>

      <el-form-item label="服务器" prop="serverAddr">
        <el-select
          v-model="queryParams.serverAddr.operator"
          placeholder="请选择条件"
          clearable
          style="width: 100px; margin-right: 10px"
        >
          <el-option
            v-for="dict in getStrDictOptions(DICT_TYPE.SYSTEM_OPERATOR_TYPE)"
            :key="dict.value"
            :label="dict.label"
            :value="dict.value"
          />
        </el-select>
        <el-input
          v-model="queryParams.serverAddr.value"
          placeholder="请输入服务器地址"
          clearable
          class="!w-200px"
        />
      </el-form-item>

      <el-form-item label="集群" prop="cluster">
        <el-select
          v-model="queryParams.cluster.operator"
          placeholder="请选择条件"
          clearable
          style="width: 100px; margin-right: 10px"
        >
          <el-option
            v-for="dict in getStrDictOptions(DICT_TYPE.SYSTEM_OPERATOR_TYPE)"
            :key="dict.value"
            :label="dict.label"
            :value="dict.value"
          />
        </el-select>
        <el-input
          v-model="queryParams.cluster.value"
          placeholder="请输入集群名称"
          clearable
          class="!w-200px"
        />
      </el-form-item>

      <el-form-item label="追踪ID" prop="traceId">
        <el-select
          v-model="queryParams.traceId.operator"
          placeholder="请选择条件"
          clearable
          style="width: 100px; margin-right: 10px"
        >
          <el-option
            v-for="dict in getStrDictOptions(DICT_TYPE.SYSTEM_OPERATOR_TYPE)"
            :key="dict.value"
            :label="dict.label"
            :value="dict.value"
          />
        </el-select>
        <el-input
          v-model="queryParams.traceId.value"
          placeholder="请输入追踪ID"
          clearable
          class="!w-200px"
        />
      </el-form-item>

      <el-form-item label="会话ID" prop="sessionId">
        <el-select
          v-model="queryParams.sessionId.operator"
          placeholder="请选择条件"
          clearable
          style="width: 100px; margin-right: 10px"
        >
          <el-option
            v-for="dict in getStrDictOptions(DICT_TYPE.SYSTEM_OPERATOR_TYPE)"
            :key="dict.value"
            :label="dict.label"
            :value="dict.value"
          />
        </el-select>
        <el-input
          v-model="queryParams.sessionId.value"
          placeholder="请输入会话ID"
          clearable
          class="!w-200px"
        />
      </el-form-item>

      <el-form-item label="用户ID" prop="userId">
        <el-select
          v-model="queryParams.userId.operator"
          placeholder="请选择条件"
          clearable
          style="width: 100px; margin-right: 10px"
        >
          <el-option
            v-for="dict in getStrDictOptions(DICT_TYPE.SYSTEM_OPERATOR_TYPE)"
            :key="dict.value"
            :label="dict.label"
            :value="dict.value"
          />
        </el-select>
        <el-input
          v-model="queryParams.userId.value"
          placeholder="请输入用户ID"
          clearable
          class="!w-200px"
        />
      </el-form-item>

      <el-form-item label="日志类别" prop="logCategory">
        <el-select
          v-model="queryParams.logCategory.operator"
          placeholder="请选择条件"
          clearable
          style="width: 100px; margin-right: 10px"
        >
          <el-option
            v-for="dict in getStrDictOptions(DICT_TYPE.SYSTEM_OPERATOR_TYPE)"
            :key="dict.value"
            :label="dict.label"
            :value="dict.value"
          />
        </el-select>
        <el-input
          v-model="queryParams.logCategory.value"
          placeholder="请输入日志类别"
          clearable
          class="!w-200px"
        />
      </el-form-item>

      <el-form-item label="日志内容" prop="message">
        <el-select
          v-model="queryParams.message.operator"
          placeholder="请选择条件"
          clearable
          style="width: 100px; margin-right: 10px"
        >
          <el-option
            v-for="dict in getStrDictOptions(DICT_TYPE.SYSTEM_OPERATOR_TYPE)"
            :key="dict.value"
            :label="dict.label"
            :value="dict.value"
          />
        </el-select>
        <el-input
          v-model="queryParams.message.value"
          placeholder="请输入日志内容"
          clearable
          class="!w-200px"
        />
      </el-form-item>

      <el-form-item label="执行时长" prop="duration">
        <el-select
          v-model="queryParams.duration.operator"
          placeholder="请选择条件"
          clearable
          style="width: 100px; margin-right: 10px"
        >
          <el-option
            v-for="dict in getStrDictOptions(DICT_TYPE.SYSTEM_OPERATOR_TYPE)"
            :key="dict.value"
            :label="dict.label"
            :value="dict.value"
          />
        </el-select>
        <el-input
          v-model="queryParams.duration.value"
          placeholder="请输入执行时长(ms)"
          clearable
          class="!w-200px"
        />
      </el-form-item>

      <el-form-item>
        <el-button @click="handleQuery"><Icon icon="ep:search" class="mr-5px" /> 搜索</el-button>
        <el-button @click="resetQuery"><Icon icon="ep:refresh" class="mr-5px" /> 重置</el-button>
      </el-form-item>
    </el-form>
  </ContentWrap>

  <!-- 列表 -->
  <!-- 列表 -->
  <ContentWrap>
    <div class="log-list-container">
      <div v-for="(item, index) in paginatedList" :key="index" class="log-item">
        <!-- 标签区域 -->
        <div class="log-header">
          <span class="log-time">{{ millisecondFormatter(null, null, item.createdOn, null) }}</span>
          <span class="log-ip">{{ item.serverAddr }}</span>
          <span v-if="item.version" class="log-version">当前版本号: {{ item.version }}</span>
          <!-- <span class="log-brand">品牌: {{ item.brand }}</span>
        <span class="log-namespace">K8S命名空间: {{ item.namespace }}</span> -->
          <span class="log-duration" v-if="item.duration">{{ item.duration }}ms</span>
          <span class="log-link" @click="viewDetail(item)">会话</span>
          <span class="log-link">链路</span>
        </div>

        <!-- 操作内容 -->
        <div class="log-content">
          {{ item.message }}
        </div>
      </div>
    </div>

    <!-- 分页组件 -->
    <Pagination
      :total="total"
      v-model:page="currentPage"
      v-model:limit="pageSize"
      @pagination="handlePagination"
      class="mt-10px"
    />
  </ContentWrap>

  <!-- 日志详情弹窗 -->
  <el-dialog v-model="dialogVisible" title="日志详情" width="70%" top="5vh">
    <el-table
      :data="detailData.children"
      style="width: 100%"
      row-key="seqId"
      :show-overflow-tooltip="true"
    >
      <el-table-column type="expand">
        <template #default="props">
          <el-form label-width="100px" label-position="left" class="log-detail-form">
            <el-row>
              <el-col :span="12">
                <el-form-item label="时间:">
                  {{ millisecondFormatter(null, null, props.row.createdOn, null) }}
                </el-form-item>
              </el-col>
              <el-col :span="12">
                <el-form-item label="日志级别:">
                  <el-tag :type="getLevelType(props.row.level)">
                    {{ props.row.level }}
                  </el-tag>
                </el-form-item>
              </el-col>
            </el-row>
            <el-row>
              <el-col :span="12">
                <el-form-item label="应用名称:">
                  {{ props.row.appName }}
                </el-form-item>
              </el-col>
              <el-col :span="12">
                <el-form-item label="服务器地址:">
                  {{ props.row.serverAddr }}
                </el-form-item>
              </el-col>
            </el-row>
            <el-row>
              <el-col :span="12">
                <el-form-item label="集群:">
                  {{ props.row.cluster }}
                </el-form-item>
              </el-col>
              <el-col :span="12">
                <el-form-item label="文件名:">
                  {{ props.row.filename }}
                </el-form-item>
              </el-col>
            </el-row>
            <el-row>
              <el-col :span="12">
                <el-form-item label="行号:">
                  {{ props.row.lineno }}
                </el-form-item>
              </el-col>
              <el-col :span="12">
                <el-form-item label="追踪ID:">
                  {{ props.row.traceId }}
                </el-form-item>
              </el-col>
            </el-row>
            <el-row>
              <el-col :span="12">
                <el-form-item label="会话ID:">
                  {{ props.row.sessionId }}
                </el-form-item>
              </el-col>
              <el-col :span="12">
                <el-form-item label="用户ID:">
                  {{ props.row.userId }}
                </el-form-item>
              </el-col>
            </el-row>
            <el-row>
              <el-col :span="12">
                <el-form-item label="序列ID:">
                  {{ props.row.seqId }}
                </el-form-item>
              </el-col>
              <el-col :span="12">
                <el-form-item label="日志类别:">
                  {{ props.row.logCategory }}
                </el-form-item>
              </el-col>
            </el-row>
            <el-row>
              <el-col :span="12">
                <el-form-item label="执行时长:"> {{ props.row.duration }} ms </el-form-item>
              </el-col>
            </el-row>
            <el-form-item label="日志内容:">
              <div class="log-message-detail">
                {{ props.row.message }}
              </div>
            </el-form-item>
          </el-form>
        </template>
      </el-table-column>
      <el-table-column prop="createdOn" label="时间" width="180">
        <template #default="scope">
          {{ millisecondFormatter(null, null, scope.row.createdOn, null) }}
        </template>
      </el-table-column>
      <el-table-column prop="level" label="日志级别" width="100">
        <template #default="scope">
          <el-tag :type="getLevelType(scope.row.level)">
            {{ scope.row.level }}
          </el-tag>
        </template>
      </el-table-column>
      <el-table-column prop="message" label="日志内容" effect />
      <el-table-column prop="serverAddr" label="服务器地址" width="150" />
      <el-table-column prop="duration" label="执行时长(ms)" width="120" />
    </el-table>
    <template #footer>
      <span class="dialog-footer">
        <el-button @click="dialogVisible = false">关闭</el-button>
      </span>
    </template>
  </el-dialog>
</template>
<script lang="ts" setup>
import { DICT_TYPE, getStrDictOptions } from '@/utils/dict'
import { dateFormatter } from '@/utils/formatTime'
import * as OpLogApi from '@/api/system/operatelog'
import dayjs from 'dayjs'
import * as DateUtil from '@/utils/formatTime'
import { generateUUID } from '@/utils'

defineOptions({ name: 'SystemLogQuery' })

const message = useMessage() // 消息弹窗
const { t } = useI18n() // 国际化

const loading = ref(false) // 列表的加载中
const list = ref([]) // 列表的数据
const paginatedList = ref([]) // 分页后的数据
const total = ref(0) // 总记录数
const currentPage = ref(1) // 当前页码
const pageSize = ref(10) // 每页显示条数
const dialogVisible = ref(false) // 详情弹窗显示状态
const detailData = ref({}) // 详情数据

const shortcuts = [
  {
    text: '昨天',
    value: () => DateUtil.getDayRange(new Date(), -1)
  },
  {
    text: '最近7天',
    value: () => DateUtil.getLast7Days()
  },
  {
    text: '本月',
    value: () => [dayjs().startOf('M'), dayjs().subtract(1, 'd')]
  },
  {
    text: '最近30天',
    value: () => DateUtil.getLast30Days()
  },
  {
    text: '最近1年',
    value: () => DateUtil.getLast1Year()
  }
]

const queryParams = reactive({
  times: [],
  level: {
    key: 'level',
    operator: '$eq',
    value: ''
  },
  appName: {
    key: 'appName',
    operator: '$eq',
    value: ''
  },
  serverAddr: {
    key: 'serverAddr',
    operator: '$eq',
    value: ''
  },
  cluster: {
    key: 'cluster',
    operator: '$eq',
    value: ''
  },
  traceId: {
    key: 'traceId',
    operator: '$eq',
    value: ''
  },
  sessionId: {
    key: 'sessionId',
    operator: '$eq',
    value: ''
  },
  userId: {
    key: 'userId',
    operator: '$eq',
    value: ''
  },
  logCategory: {
    key: 'logCategory',
    operator: '$eq',
    value: ''
  },
  message: {
    key: 'message',
    operator: '$contains',
    value: ''
  },
  duration: {
    key: 'duration',
    operator: '$gt',
    value: ''
  },
  filters: [],
  start_time: '',
  end_time: '',
  queryId: generateUUID()
})
const queryFormRef = ref() // 搜索的表单
const refreshTable = ref(true) // 重新渲染表格状态

// 毫秒级时间格式化函数
const millisecondFormatter = (row: any, column: any, cellValue: any, index: any) => {
  if (!cellValue) return ''
  // 如果是时间戳格式，转换为Date对象
  const date = typeof cellValue === 'string' ? new Date(cellValue) : new Date(cellValue)
  if (isNaN(date.getTime())) return cellValue

  // 格式化为 YYYY-MM-DD HH:mm:ss.SSS
  const year = date.getFullYear()
  const month = String(date.getMonth() + 1).padStart(2, '0')
  const day = String(date.getDate()).padStart(2, '0')
  const hours = String(date.getHours()).padStart(2, '0')
  const minutes = String(date.getMinutes()).padStart(2, '0')
  const seconds = String(date.getSeconds()).padStart(2, '0')
  const milliseconds = String(date.getMilliseconds()).padStart(3, '0')

  return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}.${milliseconds}`
}

// 获取日志级别对应的标签类型
const getLevelType = (level: string) => {
  switch (level) {
    case 'ERROR':
      return 'danger'
    case 'WARN':
      return 'warning'
    case 'INFO':
      return 'success'
    case 'DEBUG':
      return 'info'
    default:
      return ''
  }
}

// 构建过滤条件
const buildFilters = () => {
  const filters: Array<{ key: string; operator: string; value: any }> = []

  // 处理时间范围
  if (queryParams.times && queryParams.times.length === 2) {
    queryParams.start_time = queryParams.times[0]
    queryParams.end_time = queryParams.times[1]
  }

  // 处理各个字段的过滤条件
  const fields = [
    'level',
    'appName',
    'serverAddr',
    'cluster',
    'filename',
    'traceId',
    'sessionId',
    'userId',
    'logCategory',
    'message',
    'duration'
  ]

  fields.forEach((field) => {
    const fieldConfig = queryParams[field]
    if (
      fieldConfig &&
      fieldConfig.value !== undefined &&
      fieldConfig.value !== '' &&
      fieldConfig.operator !== '*'
    ) {
      // 特殊处理数字类型字段
      let value = fieldConfig.value
      if (field === 'userId' || field === 'duration') {
        const numValue = Number(value)
        if (!isNaN(numValue)) {
          value = numValue
        }
      }
      const operator = fieldConfig.operator == '$eq' ? '' : fieldConfig.operator

      filters.push({
        key: fieldConfig.key,
        operator: operator,
        value: value
      })
    }
  })

  return filters
}

// 计算分页数据
const computePaginatedList = () => {
  const start = (currentPage.value - 1) * pageSize.value
  const end = start + pageSize.value
  paginatedList.value = list.value.slice(start, end)
}

interface LogItem {
  createdOn: string // 时间戳
  serverAddr: string // IP 地址
  version: string // 版本号
  brand: string // 品牌
  namespace: string // K8S 命名空间
  duration?: string // 执行耗时
  message: string // 日志内容
}

const getList = async () => {
  loading.value = true
  try {
    const filters = buildFilters()
    const queryParam = {
      start_time: queryParams.times?.[0] ?? '',
      end_time: queryParams.times?.[1] ?? '',
      queryId: queryParams.queryId,
      filters
    }

    const res = await OpLogApi.queryLogFile(queryParam)
    list.value = res || []

    // 转换数据格式
    list.value = list.value.map((item) => ({
      ...item,
      createdOn: item.createdOn,
      serverAddr: item.serverAddr,
      version: item.version,
      duration: item.duration ? `${item.duration}ms` : '',
      message: item.message || ''
    }))

    total.value = list.value.length
    computePaginatedList()
  } finally {
    loading.value = false
  }
}

/** 搜索按钮操作 */
const handleQuery = () => {
  currentPage.value = 1
  getList()
}

/** 重置按钮操作 */
const resetQuery = () => {
  currentPage.value = 1
  queryFormRef.value.resetFields()
  // 重置所有查询条件
  queryParams.times = []
  Object.keys(queryParams).forEach((key) => {
    if (
      typeof queryParams[key] === 'object' &&
      queryParams[key] !== null &&
      'value' in queryParams[key]
    ) {
      queryParams[key].value = ''
    }
  })
  handleQuery()
}

/** 分页处理 */
const handlePagination = () => {
  computePaginatedList()
}

/** 查看详情 */
const viewDetail = (row: any) => {
  detailData.value = row
  console.log(row)
  dialogVisible.value = true
}

/** 初始化 **/
onMounted(async () => {
  await getList()
})
</script>
<style scoped>
.log-message-detail {
  min-height: 100px;
  padding: 12px;
  word-break: break-all;
  white-space: pre-wrap;
  background-color: #f5f7fa;
  border-radius: 4px;
}

.log-list-container {
  margin-top: 16px;
}

.log-item {
  padding: 12px 0;
  border-bottom: 1px solid #ebeef5;
  transition: background-color 0.2s ease;
}

.log-item:hover {
  background-color: #f5f7fa;
}

.log-header {
  display: flex;
  margin-bottom: 8px;
  font-size: 12px;
  color: #666;
  gap: 8px;
  align-items: center;
}

.log-time {
  padding: 2px 6px;
  font-size: 12px;
  color: white;
  background-color: #409eff;
  border-radius: 4px;
}

.log-ip,
.log-version,
.log-brand,
.log-namespace,
.log-duration {
  padding: 2px 6px;
  font-size: 12px;
  background-color: #f5f7fa;
  border: 1px solid #dcdfe6;
  border-radius: 4px;
}

.log-link {
  padding: 2px 6px;
  font-size: 12px;
  color: #409eff;
  cursor: pointer;
  background-color: #e6f7ff;
  border-radius: 4px;
}

.log-content {
  margin: 0;
  font-family: 'Courier New', monospace;
  line-height: 1.5;
  color: #333;
  word-break: break-all;
  white-space: pre-wrap;
}
</style>
